home *** CD-ROM | disk | FTP | other *** search
/ Grand Slam 3 / Grand Slam 3.iso / 023 / dgtrekr3.arj / DRV_SRC.EXE / MYMIDI.ASM < prev    next >
Assembly Source File  |  1994-12-27  |  7KB  |  298 lines

  1. .MODEL          LARGE,C
  2. .386
  3.  
  4. include         driver.inc
  5. include         middrivr.inc
  6.  
  7. assume cs:@code, ds:nothing, ss:nothing        ; assume CS as default segment
  8.  
  9. .CODE
  10. ;-----------------------------------------
  11. ; Header
  12. ;-----------------------------------------
  13. ORG     0
  14.         db      "MIDIDRV",EOF
  15.         dw      offset dispatcher
  16.         dw      offset infoString
  17.  
  18. ;-----------------------------------------
  19. ; Data
  20. ;-----------------------------------------
  21. infoString      db      "generic MIDI driver for no-MIDI",0
  22.  
  23. oldISR          dd      ?               ; old interrupt service routine
  24. irq             db      5               ; interrupt request for MIDI card
  25. irqMask         db      ?               ; interrupt mask register
  26. irqMask2        db      ?               ; cascaded interrupt mask register
  27. port            dw      300h            ; I/O address of MIDI card
  28.  
  29. clientFunction  dd      0               ; callback function for MIDI messages
  30.  
  31. dataNeeded      dw      0               ; data bytes needed for current cmd
  32. dataMissing     dw      0               ; data bytes missing for complete msg
  33.  
  34. midiCmd         label   byte            ; first byte of buffer is the command
  35. msgBuffer       db      16 dup (?)
  36. bufferOffset    dw      1               ; buffer offset for next data byte
  37.  
  38. ;-----------------------------------------
  39. ; Code
  40. ;-----------------------------------------
  41. dispatcher      proc 
  42.     cmp     bx,MAXFN
  43.     jnb     error
  44.     shl     bx,1
  45.     jmp     function[bx]
  46. error:
  47.     mov     ax,ERR_BadFunction
  48.     ret
  49.  
  50. function label  word
  51.     dw      offset drvInit
  52.     dw      offset drvSetClient
  53.     dw      offset drvWrite
  54.     dw      offset drvTerminate
  55.     MAXFN equ ($-offset function)/size word
  56. dispatcher      endp
  57.  
  58. ;--------------------------------------------------
  59.  
  60. drvInit         proc
  61.     LOCAL   buffer[5] :DWORD, tmpMask :BYTE
  62.  
  63.     xor     ax,ax
  64.     mov     es,ax
  65.  
  66. ; add code here to locate irq
  67.  
  68.     movzx   bx,irq
  69.     cmp     bx,8
  70.     jb      @F
  71.     add     bx,70h-8-8
  72. @@:     add     bx,8
  73.     shl     bx,2
  74.     mov     eax,es:[bx]
  75.     mov     oldISR,eax
  76.     
  77.     ; check if there is already a driver installed
  78.     push    eax
  79.     pop     ax
  80.     pop     fs
  81.     mov     ax,ERR_Busy
  82.     cmp     dword ptr fs:[0004h],"VRD"+EOF shl 24   ; reverse "DRV",EOF
  83.     je      done
  84.     
  85.     ; install new handler
  86.     mov     es:[bx+0],offset midiHandler
  87.     mov     es:[bx+2],cs
  88.  
  89. enableIRQ:
  90.     mov     cl,irq
  91.     mov     dx,21h
  92.     cmp     cl,8
  93.     jb      loIrq
  94.   hiIrq:      
  95.     mov     dx,0A1h         ; address of 2nd int ctrl
  96.     in      al,21h          ; enable cascaded irq 2
  97.     mov     irqMask2,al
  98.     and     al,NOT 04h
  99.     out     21h,al
  100.     sub     cl,8
  101.   loIrq:
  102.     mov     ah,0FEh
  103.     rol     ah,cl
  104.     in      al,21h          ; read mask
  105.     mov     irqMask,al      ; save mask
  106.     and     al,ah           ; clear the irq mask for MIDI irq
  107.     out     21h,al          ; write mask
  108.  
  109.     mov     ax,ERR_Ok
  110.  
  111. done:        
  112.     cmp     ax,1
  113.     cmc
  114.     ret
  115. drvInit         endp
  116.  
  117. ;=======================================
  118. drvSetClient proc
  119.     mov     clientFunction,eax
  120.     mov     midiCmd,0               ; current midi command unknown
  121.     
  122.     or      eax,eax
  123.     jz      stopMidi
  124.  
  125. startMIDI:
  126.     
  127. ; add code here to enable MIDI receive
  128.     jmp     done
  129.  
  130. stopMidi:
  131.  
  132. ; add code here to disable MIDI receive
  133.  
  134. done:
  135.     mov     ax,ERR_Ok
  136.     clc
  137.     ret
  138. drvSetClient endp
  139.  
  140. ;=======================================
  141. drvWrite        proc,
  142.     buffer :ptr byte, bufferLen :word
  143.  
  144.     les     bx,buffer        
  145.     mov     cx,bufferLen
  146.     jcxz    done
  147. nextByte:
  148.     mov     al,es:[bx]
  149.  
  150. ; add code here to make a MIDI out
  151.  
  152.     inc     bx
  153.     loop    nextByte
  154. done:
  155.     ret
  156. drvWrite        endp
  157.  
  158. ;========================================
  159. drvTerminate proc uses es
  160.     cmp     irq,0           ; if irq wasn't found, then don't uninstall it
  161.     je      exit
  162.  
  163.     cmp     clientFunction,0  ; stop MIDI reception
  164.     je      notRunning
  165.     mov     eax,0
  166.     call    drvSetClient
  167. notRunning:
  168.  
  169.     movzx   bx,irq
  170.     mov     dx,21h          ; restore old interrupt masks
  171.     cmp     bx,8        
  172.     jb      loIrq
  173. hiIrq:
  174.     mov     al,irqMask2
  175.     out     21h,al
  176.     mov     dx,0A1h
  177.     add     bx,70h-8-8
  178. loIrq:
  179.     mov     al,irqMask
  180.     out     dx,al
  181.     
  182.     xor     ax,ax           ; restore old interrupt service routine
  183.     mov     es,ax
  184.     add     bx,8
  185.     shl     bx,2
  186.     mov     eax,oldISR
  187.     mov     es:[bx],eax
  188.  
  189. exit:
  190.     clc
  191.     mov     ax,ERR_Ok
  192.     ret
  193. drvTerminate endp
  194.  
  195.  
  196. ;.----------------------------------.
  197. ;|        internal functions        |
  198. ;`----------------------------------'
  199.  
  200. ;=======================================
  201. midiHandler proc far
  202.     push    ax
  203.     push    bx
  204.     push    dx
  205.     sti
  206.  
  207. ; add code here to make a MIDI in 
  208. ;       in    al,MIDIPORT        
  209.  
  210.     ; if there is no client, drop the message
  211.     cmp     clientFunction,0
  212.     je      exit
  213.  
  214.     test    al,80h          ; is it a MIDI command (bit 7=1) ?
  215.     jnz     manageMidiCommand
  216.  
  217.     cmp     midiCmd,0       ; drop data byte if command is unknown
  218.     je      exit
  219.  
  220.     mov     bx,bufferOffset ; store the data byte in the message buffer
  221.     mov     msgBuffer[bx],al
  222.     inc     bufferOffset
  223.  
  224.     dec     dataMissing
  225.     js      exit            ; more data than expected, drop it
  226.     jmp     execCommand     ; execute if all data was read
  227.  
  228. manageMidiCommand:
  229.     cmp     al,0F8h         ; drop clock message
  230.     je      exit
  231.     cmp     al,0FEh         ; drop active sensing message
  232.     je      exit
  233.     
  234.     ; get the number of data bytes for the command
  235.     mov     dx,2
  236.     cmp     al,0C0h
  237.     jb      gotArgNum       ; 8x,9x,Ax,Bx
  238.     
  239.     mov     dx,1
  240.     cmp     al,0E0h         ; Cx,Dx
  241.     jb      gotArgNum
  242.     
  243.     mov     dx,2
  244.     cmp     al,0F0h
  245.     jb      gotArgNum       ; Ex
  246.     
  247.     mov     dx,0FFFFh       ; (actually drop all data)
  248.     je      gotArgNum       ; F0 (system exclusive)
  249.     
  250.     mov     dx,2
  251.     cmp     al,0F2h
  252.     jbe     gotArgNum
  253.     
  254.     mov     dx,1
  255.     cmp     al,0F3h
  256.     je      gotArgNum
  257.     
  258.     mov     dx,0
  259. gotArgNum:
  260.     mov     dataNeeded,dx
  261.     mov     dataMissing,dx
  262.     mov     bufferOffset,1
  263.     mov     midiCmd,al
  264.  
  265. execCommand:
  266.     cmp     dataMissing,0
  267.     jne     exit            ; still data missing, so nothing to do
  268.     
  269.     mov     dx,dataNeeded   ; reinitialize command
  270.     mov     dataMissing,dx
  271.  
  272.     pushad                  ; save registers
  273.     push    es
  274.  
  275.     push    cs
  276.     push    offset msgBuffer        ; call the C client function
  277.     call    clientFunction
  278.     add     sp,4
  279.  
  280.     pop     es
  281.     popad                   ; restore registers
  282.  
  283. exit:
  284.     mov     al,EOI
  285.     
  286.     cmp     irq,8
  287.     jb      @F
  288.     out     0A0h,al
  289. @@:     out     20h,al
  290.     pop     dx
  291.     pop     bx
  292.     pop     ax
  293.     iret
  294. midiHandler     endp
  295.  
  296.  
  297. END
  298.